/*
*
*   业务：门户网站
*   作者：宫旭童
*
* */

package org.example.petitionplatformsystem.controller;

import com.aliyuncs.exceptions.ClientException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.example.petitionplatformsystem.dto.AuthenticationDTO.NameAndIdDTO;
import org.example.petitionplatformsystem.utils.HttpUtils;
import org.example.petitionplatformsystem.utils.RandomUtil;
import org.example.petitionplatformsystem.Response;
import org.example.petitionplatformsystem.converter.UsersConverter;
import org.example.petitionplatformsystem.dao.model.Authentication;
import org.example.petitionplatformsystem.dao.model.Users;
import org.example.petitionplatformsystem.dto.UserDTO.*;
import org.example.petitionplatformsystem.service.AuthenticationService;
import org.example.petitionplatformsystem.service.MsmService;
import org.example.petitionplatformsystem.service.UsersService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;


@RequestMapping("/users")
@RestController
public class UsersController {
    //用户表的服务
    private final UsersService usersService;
    //身份证表的服务
    private final AuthenticationService authenticationService;
    //发送短信验证码的服务
    private final MsmService msmService;
    //建立短信验证码的键值对。
    private final RedisTemplate<String, String> redisTemplate;    //注入redis
    @Autowired
    public UsersController(UsersService usersService,
                           AuthenticationService authenticationService,
                           MsmService msmService,
                           RedisTemplate<String, String> redisTemplate){
        this.usersService = usersService;
        this.authenticationService = authenticationService;
        this.msmService = msmService;
        this.redisTemplate = redisTemplate;
    }


    //手机号密码登录
    @PostMapping("/login")
    public Response<Void> login(@RequestBody UsersLoginDTO usersLoginDTO) throws NoSuchAlgorithmException {
        Users users = usersService.GetUsersByPhoneNumber(usersLoginDTO.getPhoneNumber());

        //利用hash算法将密码加密
        String password = usersLoginDTO.getPassword();
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(password.getBytes(StandardCharsets.UTF_8));
        String hashPassword = String.format("%064x", new BigInteger(1, hash));

        if(users != null)
            if(users.getPassword().equals(hashPassword))
                return Response.newSuccessResponse(null);
            else{
                System.out.println(hashPassword);
                return Response.newFailResponse("账户或密码不正确，登录失败。");
            }
        else
            return Response.newFailResponse("账户不存在，登录失败。");
    }

    //验证码登录
    //按手机号查询用户信息
    @PostMapping("/loginByParam/{phoneNumber}/{param}")
    public Response<UsersInfoDTO> loginByParam(@PathVariable String phoneNumber, @PathVariable String param) {
        System.out.println("phoneNumber: " + phoneNumber);
        System.out.println("param: " + param);
        String code = redisTemplate.opsForValue().get(phoneNumber);
        System.out.println("Retrieved code from Redis: " + code);

        if (code != null) {
            System.out.println("Code from Redis: " + code);
        }

        if (!Objects.isNull(code) && !code.isEmpty() && code.equals(param)) {
            return Response.newSuccessResponse(null);
        } else {
            return Response.newFailResponse("验证码错误！");
        }
    }

    //发送验证码
    @PostMapping("/send/{phoneNumber}")
    public Response<String> send(@PathVariable String phoneNumber) throws ClientException {
        System.out.println("phone   "+phoneNumber);
        //发短信验证码
        //1、从redis中获取验证码，如果获取到就直接返回
        String code = redisTemplate.opsForValue().get(phoneNumber);
        if (!Objects.isNull(code) && !code.isEmpty())
            return Response.newSuccessResponse(null);

        //2、如果获取不到，就进行阿里云发送
        code = RandomUtil.getFourBitRandom();//生成验证码的随机值
        Map<String,Object> param = new HashMap<>();
        param.put("code", code);

        //调用方法
        boolean isSend = msmService.send(param,phoneNumber);
        if(isSend) {
            //往redis中设置数据：key、value、过期值、过期时间单位  MINUTES代表分钟
            redisTemplate.opsForValue().set(phoneNumber, code,1, TimeUnit.MINUTES);
            return Response.newSuccessResponse(code);
        } else {
            return Response.newFailResponse("验证码发送出错，检查自己的手机号");
        }
    }

    //注册
    @PostMapping("/register")
    public Response<Void> register(@RequestBody UsersRegisterDTO usersRegisterDTO) throws NoSuchAlgorithmException {
        //手机号码不能重复注册
        if(usersService.onlyOnePhoneNumber(usersRegisterDTO.getPhoneNumber())){
            System.out.println("---------------------------------------");
            return Response.newFailResponse("该手机号已注册过！");
        }


        //hash加密
        String password = usersRegisterDTO.getPassword();
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(password.getBytes(StandardCharsets.UTF_8));
        String hashPassword = String.format("%064x", new BigInteger(1, hash));
        usersRegisterDTO.setPassword(hashPassword);

        //DTO转化为实体类
        Users user = UsersConverter.converterRegisterUsers(usersRegisterDTO);
        user.setIsAuthenticated(false);

        //验证码
        String code = redisTemplate.opsForValue().get(usersRegisterDTO.getPhoneNumber());
        System.out.println(code);
        if (!Objects.isNull(code) && !code.isEmpty() && code.equals(usersRegisterDTO.getParam())){
            usersService.AddUsers(user);
            return Response.newSuccessResponse(null);
        }
        else
            return Response.newFailResponse("验证码错误！");
    }

    //更改用户密码
    @PutMapping("/updateInfo") // 路径改为只包含 userId
    public Response<Void> updateUserInfo(@RequestBody UsersPasswordDTO usersPasswordDTO) throws NoSuchAlgorithmException {
        // 获取加密后的密码
        Long usersId = usersPasswordDTO.getUserId();
        String password = usersPasswordDTO.getPassword();
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(password.getBytes(StandardCharsets.UTF_8));
        String hashPassword = String.format("%064x", new BigInteger(1, hash));
        if(usersService.GetUsersById(usersId)==null)
            return Response.newFailResponse("用户不存在");

        usersService.UpdateUsersPassword(usersId, hashPassword);
        return Response.newSuccessResponse(null);
    }

    //获取用户的身份证和姓名
    @GetMapping("/getuserinfo/{phoneNumber}")
    public Response<NameAndIdDTO> getuserinfo(@PathVariable String phoneNumber){
        Users users = usersService.GetUsersByPhoneNumber(phoneNumber);
        if(users == null )
            return Response.newFailResponse("没有这样的电话号码。");
        Authentication authentication = authenticationService.GetAuthenticationByUserId(users.getUserId());
        if(authentication == null)
        {
            Users user = usersService.GetUsersByPhoneNumber(phoneNumber);
            NameAndIdDTO nameAndIdDTO = new NameAndIdDTO();
            nameAndIdDTO.setUserId(users.getUserId());
            nameAndIdDTO.setUserName(users.getUsername());
            return Response.newSuccessResponse(nameAndIdDTO,"您还没有实名认证，请先实名认证");
        }

        NameAndIdDTO nameAndIdDTO = new NameAndIdDTO();
        nameAndIdDTO.setUserName(authentication.getFullName());
        nameAndIdDTO.setIdCardNumber(authentication.getIdCardNumber());
        nameAndIdDTO.setUserId(users.getUserId());

        return Response.newSuccessResponse(nameAndIdDTO);
    }

    //统一身份认证
    @PostMapping("/authentication")
    public Response<AuthDataDTO> isAuthenticated(@RequestBody UsersAuthDTO usersAuthDTO) {
        System.out.println("idcard "+usersAuthDTO.getIdCardNumber());
        System.out.println("name "+usersAuthDTO.getFullName());
        System.out.println("userid"+usersAuthDTO.getUserId());
        return Response.newSuccessResponse(null);
//        String host = "https://authen.market.alicloudapi.com";
//        String path = "/lundear/idcard";
//        String method = "GET";
//        String appcode = "18268158e01046a09074809a6e6019e0";
//        Map<String, String> headers = new HashMap<>();
//        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
//        headers.put("Authorization", "APPCODE " + appcode);
//        Map<String, String> querys = new HashMap<>();
//        querys.put("idcard", usersAuthDTO.getIDCardNumber());
//        querys.put("name", usersAuthDTO.getFullName());
//        System.out.println("querys "+querys);
//
//        try {
//            /*
//              重要提示如下:
//              HttpUtils请从
//              https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
//              下载
//
//              相应的依赖请参照
//              https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
//             */
//            HttpResponse response =  HttpUtils.doGet(host, path, method, headers, querys);
//            System.out.println("response "+response);
//            //            获取response的body
//
//            String result = EntityUtils.toString(response.getEntity());
//            System.out.println(result);
//            ObjectMapper objectMapper = new ObjectMapper();
//            JsonNode rootNode = objectMapper.readTree(result);
//            JsonNode dataNode = rootNode.path("data");
//            AuthDataDTO data = objectMapper.treeToValue(dataNode, AuthDataDTO.class);
//
//
//            //将认证信息写入数据库，user表中是否认证变为true，auth表中将该用户的身份认证信息填写进去
//            {
//                Authentication authentication = new Authentication(usersAuthDTO,data);
//                Users users = usersService.GetUsersById(usersAuthDTO.getUserID());
//                users.setIsAuthenticated(true);
//                usersService.UpdateUsers(users);
//                authenticationService.AddAuthentication(authentication);
//            }
//            //将认证成功的信息返回给前端
//            return Response.newSuccessResponse(data);
//
//        } catch (Exception e) {
//            return Response.newFailResponse("不一致");
//        }

    }
    @GetMapping("/getWorkID/{userId}")

    public Response<Long> getWordID(@PathVariable("userId") long userId){
        Long workId = usersService.GetUsersById(userId).getWorkId();
        return Response.newSuccessResponse(workId);
    }
}
